package com.yunyike.app.data.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yunyike.app.data.dto.UserOrdersDTO;
import com.yunyike.app.data.mapper.OrdersMapper;
import com.yunyike.app.data.model.Orders;
import com.yunyike.app.data.service.IOrderService;

/**
 * @author zhengqiang.shi
 * 2015年11月26日 下午10:17:59
 */
@Service("orderServiceImpl")
public class OrderServiceImpl implements IOrderService {

	private static Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);

	@Autowired
	private OrdersMapper ordersMapper;
	
	/*@Autowired
	private IOrderCouponMappingService orderCouponMappingService;
	
	@Autowired
	private IOrderMerchandiseMappingService orderMerchandiseMappingService;
	
	@Autowired
	private IOrderRecepientMappingService orderRecepientMappingService;
	
	@Autowired
	private ICartService cartService;
	
	@Autowired
	private ICouponService couponService;*/
	
	/**
	 * 提交订单
	 *//*
	@Transactional
	public OrderDTO submitOrder(User user, String sessionId) {
		log.info("service save order.sessionId:"+sessionId);
		OrderDTO orderDTO = new OrderDTO();
		
		// 获取结算信息
		SettlementDTO settlementDTO = getSettlementDTO(sessionId);
		if(settlementDTO == null){
			log.error("service save order failed.settlementDTO is null.");
			orderDTO.setMsg(ResponseConstant.ORDER_FAILED);
			return orderDTO;
		}
		
		// 检查结算信息
		String checkSettlementDTOResult = checkSettlementDTO(settlementDTO);
		if(!ResponseConstant.ORDER_SUCCESS.equals(checkSettlementDTOResult)){
			log.error("service save order failed.checkSettlementDTO return false.");
			orderDTO.setMsg(checkSettlementDTOResult);
			return orderDTO;
		}
		
		// 保存订单
		Orders doSubmit = null;
		try {
			doSubmit = doSubmit(user, settlementDTO);
		} catch (BusinessException e) {
			throw new BusinessException("submitOrder failed."+e.getMessage(),e);
		} finally {
			if(doSubmit == null){
				throw new BusinessException("service save order failed.saveOrder has error.");
			}
		}
		
		// 清空购物车、结算等信息
		cartService.afterSubmitOrder(user, settlementDTO.getCartDTO().getShop().getShopNumber(), sessionId);
		
		log.info("service save order success.");
		orderDTO.setOrders(doSubmit);
		orderDTO.setMsg(ResponseConstant.ORDER_SUCCESS);
		return orderDTO;
	}
	
	public SettlementDTO getSettlementDTO(String sessionId){
		
		// settlement redis key
		log.info("----->> generator settlement key...");
		String settlementKey = CartConstants.settlementKey(sessionId);
		log.info("settlement key:"+settlementKey);
		
		// 获取当前结算信息
		log.info("get settlement data from redis...");
		SettlementDTO settlementDTO = null;
		try {
			settlementDTO = (SettlementDTO)JedisManager.getObject(settlementKey);
		} catch (Exception e) {
			log.error("chooseRecepient has error,message:"+e.getMessage(),e);
			return null;
		}
		
		return settlementDTO;
	}
	
	public Orders doSubmit(User user,SettlementDTO settlementDTO){
		
		Orders saveOrder = null;
		try {
			// 保存订单
			saveOrder = saveOrder(user, settlementDTO);
			if(saveOrder == null){
				throw new BusinessException("saveOrder has error");
			}
			
			// 保存订单使用的收货信息
			saveOrderRecepientMapping(saveOrder.getOrderId(), settlementDTO);
			
			// 保存订单使用的优惠券
			saveOrderCouponMapping(saveOrder.getOrderId(), settlementDTO);
			
			// 保存订单购买的商品
			saveOrderMerchandiseMapping(saveOrder.getOrderId(), settlementDTO);
		} catch (Exception e) {
			throw new BusinessException("doSubmit has error,message:"+e.getMessage(),e);
		}
		
		return saveOrder;
	}
	
	private void saveOrderRecepientMapping(String orderId, SettlementDTO settlementDTO) {
		
		Recepient recepient = settlementDTO.getRecepient();
		if(recepient == null){
			log.info("submit order recepient is null,throw exception.");
			throw new DataNotFoundException();
		}
		
		OrderRecepientMapping orm = new OrderRecepientMapping();
		orm.setOrderId(orderId);
		orm.setIsDefault(recepient.getIsDefault());
		orm.setRecepientAddress(recepient.getRecepientAddress());
		orm.setRecepientAreaId(recepient.getRecepientAreaId());
		orm.setRecepientAreaName(recepient.getRecepientAreaName());
		orm.setRecepientCityId(recepient.getRecepientCityId());
		orm.setRecepientCityName(recepient.getRecepientCityName());
		orm.setRecepientEmail(recepient.getRecepientEmail());
		orm.setRecepientId(recepient.getRecepientId());
		orm.setRecepientIdCard(recepient.getRecepientIdCard());
		orm.setRecepientIdCardPhoto(recepient.getRecepientIdCardPhoto());
		orm.setRecepientName(recepient.getRecepientName());
		orm.setRecepientPostCode(recepient.getRecepientPostCode());
		orm.setRecepientProvinceId(recepient.getRecepientProvinceId());
		orm.setRecepientProvinceName(recepient.getRecepientProvinceName());
		orm.setRecepientStatus(recepient.getRecepientStatus());
		orm.setRecepientTel(recepient.getRecepientTel());
		orm.setUserId(recepient.getUserId());
		
		int insert = orderRecepientMappingService.insert(orm);
		
		if(insert != CommonConstant.NUMBER_1){
			log.info("submit order save order recepient failed.result is:"+insert);
			throw new BusinessException();
		}
		
	}

	public void saveOrderMerchandiseMapping(String saveOrder, SettlementDTO settlementDTO){
		
		List<CartSkuDTO> cartSkuDTOList = settlementDTO.getCartDTO().getCartSkuDTOList();
		if(cartSkuDTOList == null || cartSkuDTOList.isEmpty()){
			log.error("saveOrderMerchandiseMapping cartSkuDTOList is null.");
			throw new BusinessException();
		}
		
		for (CartSkuDTO cartSkuDTO : cartSkuDTOList) {
			
			Merchandise merchandise = cartSkuDTO.getMerchandise();
			
			OrderMerchandiseMapping omm = new OrderMerchandiseMapping();
			omm.setOrderId(saveOrder);
			omm.setCtime(merchandise.getCtime());
			omm.setMerchandiseBarcode(merchandise.getMerchandiseBarcode());
			omm.setMerchandiseCurrency(merchandise.getMerchandiseCurrency());
			omm.setMerchandiseDesc(merchandise.getMerchandiseDesc());
			omm.setMerchandiseDomesticPrice(merchandise.getMerchandiseDomesticPrice());
			omm.setMerchandiseIcon(merchandise.getMerchandiseIcon());
			omm.setMerchandiseId(merchandise.getMerchandiseId());
			omm.setMerchandiseNameCn(merchandise.getMerchandiseNameCn());
			omm.setMerchandiseNameEn(merchandise.getMerchandiseNameEn());
			omm.setMerchandiseNumber(merchandise.getMerchandiseNumber());
			omm.setMerchandisePrice(merchandise.getMerchandisePrice());
			omm.setMerchandiseQrcode(merchandise.getMerchandiseQrcode());
			omm.setMerchandiseSpec(merchandise.getMerchandiseSpec());
			omm.setMerchandiseVolume(merchandise.getMerchandiseVolume());
			omm.setMerchandiseWeight(merchandise.getMerchandiseWeight());
			omm.setShopId(merchandise.getShopId());
			omm.setMerchandiseQty(cartSkuDTO.getQty());
			int insert = 0;
			try {
				insert = orderMerchandiseMappingService.insert(omm);
			} catch (Exception e) {
				throw new BusinessException("orderMerchandiseMappingService.insert has error.message:"+e.getMessage(),e);
			} finally {
				if(insert == 0){
					throw new BusinessException("orderMerchandiseMappingService.insert return 0,return false.");
				}
			}
			
		}
	}
	
	public void saveOrderCouponMapping(String saveOrder, SettlementDTO settlementDTO){
		
		List<Coupon> couponList = settlementDTO.getCouponList();
		if(couponList == null || !couponList.isEmpty()){
			log.info("orderId:"+saveOrder+" 未使用优惠券.");
			return;
		}
		
		for (Coupon coupon : couponList) {
			OrderCouponMapping ocm = new OrderCouponMapping();
			ocm.setOrderCouponMappingId(UUID.randomUUID().toString());
			ocm.setOrderId(saveOrder);
			ocm.setCouponId(coupon.getCouponId());
			log.info("start orderCouponMappingService.insert ,ocm:{}",ocm);
			int insert = 0;
			int updateCoupon = 0;
			try {
				// 插入订单优惠券对应表
				insert = orderCouponMappingService.insert(ocm);
				
				// 更新优惠券状态
				Coupon c = new Coupon();
				c.setCouponId(coupon.getCouponId());
				c.setCouponStatus(CouponConstants.COUPON_STATUS_1);
				updateCoupon = couponService.updateCoupon(c);
			} catch (Exception e) {
				log.error("orderCouponMappingService.insert has error.message:"+e.getMessage(),e);
				throw new BusinessException();
			} finally {
				if(insert == 0 || updateCoupon == 0){
					log.error("orderCouponMappingService.insert or updateCoupon return 0");
					throw new BusinessException();
				}
			}
		}
	}
	
	public Orders saveOrder(User user, SettlementDTO settlementDTO){
		
		String orderId = UUID.randomUUID().toString();
		
		Orders orders = new Orders();
		orders.setOrderId(orderId);
		orders.setOrderNumber(PKUtils.getPrimaryKey());
		orders.setShopName(settlementDTO.getCartDTO().getShop().getShopNameCn());
		orders.setShopId(settlementDTO.getCartDTO().getShop().getShopId());
		orders.setShopperId(settlementDTO.getShopper().getShopperId());
		orders.setUserId(user.getUserId());
		orders.setOrderStatus(OrderConstants.ORDER_STATUS_0);
		orders.setOrderDateTime(new Date());
		
		// 设置订单价格
		setPrice(user, settlementDTO, orders);
		
		int result = 0;
		try {
			result = ordersMapper.insertSelective(orders);
		} catch (Exception e) {
			log.error("orderMapper.insertSelective has error.message:"+e.getMessage(),e);
			throw new BusinessException();
		} finally {
			if(result == 0){
				log.error("orderMapper.insertSelective result is 0");
				throw new BusinessException();
			}
		}
		
		Orders curOrders = ordersMapper.selectByPrimaryKey(orderId);
		
		return curOrders;
	}
	
	private void setPrice(User user,SettlementDTO settlementDTO, Orders orders) {
		
		
		double orderPrice = 0;	// 订单金额
		double orderDiscountPrice = 0;	// 订单优惠金额
		double orderFreightPrice = 0;	// 运费
		double orderFreightDiscountPrice = 0;	// 运费优惠金额
		
		double totalWeight = 0;		// 总重量
		
		// 商品总节省金额
		BigDecimal saveAmount = new BigDecimal(0);
		// 商品总数量
		int totalNumber = 0;
		
		CartDTO cartDTO = settlementDTO.getCartDTO();
		
		List<CartSkuDTO> cartSkuDTOList = cartDTO.getCartSkuDTOList();
		for (CartSkuDTO cartSkuDTO : cartSkuDTOList) {
			
			Merchandise merchandise = cartSkuDTO.getMerchandise();
			Double merchandisePrice = merchandise.getMerchandisePrice();
			int qty = cartSkuDTO.getQty();
			
			orderPrice += merchandisePrice * qty;	// 单商品小计
			totalWeight += merchandise.getMerchandiseWeight();
			totalNumber += qty;
			// 国内价
			Double merchandiseDomesticPrice = merchandise.getMerchandiseDomesticPrice() * cartSkuDTO.getQty();
			
			// 换算人民币后的商品价格
			double exchangeRate = ExchangeRateUtils.exchangeRate(EnumExchangeRate.CNY, orderPrice);
			
			// 商品总节省金额
			saveAmount = saveAmount.add(new BigDecimal(merchandiseDomesticPrice - exchangeRate));
						
		
		}
		
		orderFreightPrice = Math.ceil(totalWeight/1000)*10;
		
		// 计算活动
		List<ShopPromotion> shopPromotionList = cartDTO.getShopPromotionList();
		
		if(shopPromotionList != null && !shopPromotionList.isEmpty()){
			
			// 排序
			Collections.sort(shopPromotionList, new Comparator<ShopPromotion>() {

				public int compare(ShopPromotion o1, ShopPromotion o2) {
					
					return o1.getOrderPrice().compareTo(o2.getOrderPrice());
				}
			});
			
			// 匹配活动
			for (ShopPromotion shopPromotion : shopPromotionList) {
				// 满足金额
				Double price = shopPromotion.getOrderPrice();
				
				if(orderPrice >= price){
					double discountPrice = orderPrice * shopPromotion.getDiscount();// 打折后的金额
					orderDiscountPrice = orderPrice - discountPrice;	// 原价减去打折价=优惠了多少钱
					orderPrice = discountPrice;	// 订单金额
					break;
				}
			}
		}
		
		double discountPrice = orderPrice * CommonConstant.DISCOUNT;	// 固定的折扣
		orderDiscountPrice = orderPrice - discountPrice;	// 原价减去打折价=优惠了多少钱
		orderPrice = discountPrice;	// 订单金额
		
		List<Coupon> couponList = settlementDTO.getCouponList();
		if(couponList != null && !couponList.isEmpty()){
			
			for (Coupon coupon : couponList) {
				// 检查优惠券
				checkCoupon(user, orderPrice, coupon);
				
				// 现金券
				if(CommonConstant.NUMBER_0 == coupon.getCouponType()){
					// 订单金额 = 订单金额 减去 优惠券金额
					orderPrice = orderPrice - coupon.getCouponAmount();
					if(orderPrice < 0){
						// 订单金额小于0时 订单金额为0， 折扣金额为：加上订单金额
						orderDiscountPrice += orderPrice;
						orderPrice = 0;
					}else{
						// 折扣金额加上优惠券
						orderDiscountPrice += coupon.getCouponAmount();
					}
				}else{	// 物流券
					orderFreightPrice -= coupon.getCouponAmount();
					if(orderFreightPrice < 0){
						orderFreightDiscountPrice += orderFreightPrice;
						orderFreightPrice = 0;
					}else{
						orderFreightDiscountPrice += coupon.getCouponAmount();
					}
				}
			}
		}
		DecimalFormat df = new DecimalFormat("######0.00"); 
		orders.setOrderPrice(Double.valueOf(df.format(orderPrice+orderFreightPrice)));
		orders.setOrderDiscountPrice(Double.valueOf(df.format(orderDiscountPrice)));
		orders.setOrderFreightPrice(Double.valueOf(df.format(orderFreightPrice)));
		orders.setOrderFreightDiscountPrice(Double.valueOf(df.format(orderFreightDiscountPrice)));
		orders.setOrderDomisticDiscountPrice(saveAmount.doubleValue());
		orders.setTotalQty(totalNumber);
		
	}
	
	
	
	private String checkSettlementDTO(SettlementDTO settlementDTO){
		
		CartDTO cartDTO = settlementDTO.getCartDTO();
		if(cartDTO == null){
			log.info("checkSettlementDTO,cartDTO is null.");
			return ResponseConstant.ORDER_FAILED;
		}
		
		Payment payment = settlementDTO.getPayment();
		if(payment == null){
			log.info("checkSettlementDTO,payment is null.");
			return ResponseConstant.ORDER_FAILED;
		}
		
		Recepient recepient = settlementDTO.getRecepient();
		if(recepient == null){
			log.info("checkSettlementDTO,recepient is null.");
			return ResponseConstant.ORDER_FAILED_ADDRESS;
		}
		
		Shopper shopper = settlementDTO.getShopper();
		if(shopper == null){
			log.info("checkSettlementDTO,shopper is null.");
			return ResponseConstant.ORDER_FAILED;
		}
		
		return ResponseConstant.ORDER_SUCCESS;
	}
	
	private void checkCoupon(User user, double payAmount, Coupon coupon) {
		// 所属用户
		String userId = coupon.getUserId();
		if(!user.getUserId().equals(userId)){
			log.error("coupon not current user , throw exception.");
			throw new BadRequestException();
		}
		
		// 满足金额
		Double couponUsePrice = coupon.getCouponUsePrice();
		if(payAmount < couponUsePrice){
			log.error("couponUsePrice < payAmount , throw exception.");
			throw new BadRequestException();
		}
		
		// 优惠券状态
		Integer couponStatus = coupon.getCouponStatus();
		if(CommonConstant.NUMBER_0 != couponStatus){
			log.error("couponStatus not 0 , throw exception.");
			throw new BadRequestException();
		}
		
		// 优惠券开始时间
		Date couponStartDate = coupon.getCouponStartDate();
		if(new Date().compareTo(couponStartDate) < 0){
			log.error("couponStartDate > current time , throw exception.");
			throw new BadRequestException();
		}
		
		// 优惠券结束时间
		Date couponEndDate = coupon.getCouponEndDate();
		if(new Date().compareTo(couponEndDate) > 0){
			log.error("couponEndDate < current time , throw exception.");
			throw new BadRequestException();
		}
	}

	public Map<String, Integer> findOrderCountByCondition(User user, List<Integer> statusList) {
		
		// 初始化返回参数
		Map<String, Integer> ordersMap = new HashMap<String, Integer>();
		ordersMap.put("2", 0);
		ordersMap.put("3", 0);
		
		List<Orders> list;
		try {
			list = ordersMapper.findOrdersByStatus(statusList);
		} catch (Exception e) {
			log.error("ordersMapper.findOrdersByStatus has error.message:"+e.getMessage(),e);
			return ordersMap;
		}
		if(list == null || list.isEmpty()){
			return ordersMap;
		}
		int order6Qty = 0;
		int order7Qty = 0;
		for (Orders orders : list) {
			Integer orderStatus = orders.getOrderStatus();
			switch (orderStatus) {
			case OrderConstants.ORDER_STATUS_6:
				order6Qty ++;
				break;

			case OrderConstants.ORDER_STATUS_7:
				order7Qty ++;
				break;
			}
		}
		
		ordersMap.put("2", order6Qty);
		ordersMap.put("3", order7Qty);
		
		return ordersMap;
	}*/
	
	/**
	 * 根据状态获取用户的订单信息（待支付、已收货、未收货）
	 */
	public List<UserOrdersDTO> findUserOrders(UserOrdersDTO param){
		List<UserOrdersDTO>  resultList = ordersMapper.findUserOrders(param);
		if(resultList!=null&&resultList.size()>0){
			for(UserOrdersDTO dto:resultList){
				dto.setOldFreightPrice(dto.getOrderFreightPrice().add(dto.getOrderFreightDiscountPrice()));
				dto.setOldOrderPrice(dto.getOrderPrice().subtract(dto.getOrderFreightPrice()));
			}
		}
		return resultList;
	}

	@Override
	public String updateOrderStatu(UserOrdersDTO dto,Integer orderStatus) {
		Orders order= ordersMapper.selectByPrimaryKey(dto.getOrderId());
		if(order==null){
			return "订单不存在";
		}else if(!dto.getUserId().equals(order.getUserId())){
			return "您没有权限操作该订单";
		}else{
			Orders upOrder= new Orders();
			upOrder.setOrderStatus(orderStatus);
			upOrder.setOrderId(order.getOrderId());
			int result = ordersMapper.updateByPrimaryKeySelective(upOrder);
			if(result==0)return "发生异常，操作失败";
		}
		return null;
	}
}
